import tkinter as tk
from tkinter import ttk
from typing import Dict, Callable, Optional, List


class MainView:
    # 主界面

    def __init__(self, master: tk.Tk):
        self.master = master
        self.frame = tk.Frame(master)
        self._setup_ui()
        self.all_grades = {}
        self.filtered_grades = {}

    def _setup_ui(self):
        # 初始化界面组件
        self.frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        # 顶部信息栏
        top_frame = tk.Frame(self.frame)
        top_frame.pack(fill=tk.X, pady=(0, 10))

        # 欢迎信息
        self.welcome_label = tk.Label(
            top_frame,
            font=('Arial', 14, 'bold')
        )
        self.welcome_label.pack(side=tk.LEFT)

        # 统计信息
        stats_frame = tk.Frame(top_frame)
        stats_frame.pack(side=tk.RIGHT)

        self.avg_label = tk.Label(
            stats_frame,
            text="加权平均分: -",
            font=('Arial', 12),
            fg='#555555'
        )
        self.avg_label.pack(anchor=tk.E)

        self.credit_label = tk.Label(
            stats_frame,
            text="总学分: -",
            font=('Arial', 12),
            fg='#555555'
        )
        self.credit_label.pack(anchor=tk.E)

        # 搜索区域
        search_frame = tk.Frame(self.frame)
        search_frame.pack(fill=tk.X, pady=(0, 10))

        tk.Label(
            search_frame,
            text="搜索科目:",
            font=('Arial', 11)
        ).pack(side=tk.LEFT, padx=(0, 5))

        self.search_entry = tk.Entry(
            search_frame,
            width=30,
            font=('Arial', 11)
        )
        self.search_entry.pack(side=tk.LEFT, padx=5)
        self.search_entry.bind('<Return>', self._trigger_search)

        self.search_btn = tk.Button(
            search_frame,
            text="搜索",
            width=8,
            command=self._trigger_search
        )
        self.search_btn.pack(side=tk.LEFT, padx=5)

        self.clear_search_btn = tk.Button(
            search_frame,
            text="清除",
            width=8,
            command=self._trigger_clear_search
        )
        self.clear_search_btn.pack(side=tk.LEFT)

        # 操作按钮区域
        btn_frame = tk.Frame(self.frame)
        btn_frame.pack(pady=(10, 5))

        # 第一排按钮（成绩操作）
        row1_frame = tk.Frame(btn_frame)
        row1_frame.pack()

        row1_buttons = [
            ("添加成绩", 'add'),
            ("删除成绩", 'delete'),
            ("修改成绩", 'update'),
            ("刷新", 'refresh')
        ]

        for text, cmd in row1_buttons:
            btn = tk.Button(
                row1_frame,
                text=text,
                width=10,
                height=1
            )
            btn.pack(side=tk.LEFT, padx=5, pady=2)
            setattr(self, f"{cmd}_btn", btn)

        # 第二排按钮（图表和退出）
        row2_frame = tk.Frame(btn_frame)
        row2_frame.pack()

        row2_buttons = [
            ("成绩分布图", 'show_chart'),
            ("学分占比图", 'show_credit_pie'),
            ("退出登录", 'logout')
        ]

        for text, cmd in row2_buttons:
            btn = tk.Button(
                row2_frame,
                text=text,
                width=10,
                height=1
            )
            btn.pack(side=tk.LEFT, padx=5, pady=2)
            setattr(self, f"{cmd}_btn", btn)

        # 成绩表格
        self.tree = ttk.Treeview(
            self.frame,
            columns=('subject', 'score', 'credit'),
            show='headings',
            selectmode='browse',
            height=12
        )

        # 设置表格样式
        style = ttk.Style()
        style.configure("Treeview.Heading", font=('Arial', 12, 'bold'))
        style.configure("Treeview", font=('Arial', 11), rowheight=25)
        style.map("Treeview",
                  background=[('selected', '#E6E6E6')],
                  foreground=[('selected', 'black')])

        # 设置列
        columns = [
            ('subject', '科目', 200, tk.W),
            ('score', '成绩', 100, tk.CENTER),
            ('credit', '学分', 100, tk.CENTER)
        ]

        for col_id, text, width, anchor in columns:
            self.tree.heading(col_id, text=text, anchor=anchor)
            self.tree.column(col_id, width=width, anchor=anchor)

        # 滚动条
        scrollbar = ttk.Scrollbar(
            self.frame,
            orient=tk.VERTICAL,
            command=self.tree.yview
        )
        self.tree.configure(yscrollcommand=scrollbar.set)
        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 图表容器（位于表格下方）
        self.chart_frame = tk.Frame(self.frame, height=300)
        self.chart_frame.pack(fill=tk.BOTH, expand=True, pady=10)

    def clear_chart_frame(self):
        # 清空图表容器
        for widget in self.chart_frame.winfo_children():
            widget.destroy()

    def bind_commands(self, commands: Dict[str, Callable]):
        # 绑定按钮事件
        for cmd, func in commands.items():
            if hasattr(self, f"{cmd}_btn"):
                getattr(self, f"{cmd}_btn").config(command=func)

        if 'search' in commands:
            self.search_cmd = commands['search']
        if 'clear_search' in commands:
            self.clear_search_cmd = commands['clear_search']

    def _trigger_search(self, event=None):
        # 触发搜索
        if hasattr(self, 'search_cmd'):
            keyword = self.search_entry.get().strip()
            self.search_cmd(keyword)

    def _trigger_clear_search(self, event=None):
        # 清除搜索
        if hasattr(self, 'clear_search_cmd'):
            self.search_entry.delete(0, tk.END)
            self.clear_search_cmd()

    def set_username(self, username: str):
        # 设置欢迎信息
        self.welcome_label.config(text=f"欢迎, {username}")

    def update_grades(self, grades: Dict[str, Dict[str, float]],
                      weighted_avg: Optional[float] = None,
                      total_credit: Optional[float] = None,
                      is_filtered: bool = False):
        # 更新成绩显示
        # 保存原始数据
        if not is_filtered:
            self.all_grades = grades
        self.filtered_grades = grades

        # 清空表格
        self.tree.delete(*self.tree.get_children())

        # 填充新数据（带颜色标记）
        for subject, info in grades.items():
            score = info.get('score', 0)
            # 设置颜色标签
            tag = 'excellent' if score >= 90 else 'fail' if score < 60 else 'normal'
            self.tree.insert('', tk.END, values=(
                subject,
                f"{score:.1f}",
                f"{info.get('credit', 0):.1f}"
            ), tags=(tag,))

            # 配置颜色
            self.tree.tag_configure('excellent', foreground='#009933')  # 绿色
            self.tree.tag_configure('normal', foreground='#000000')  # 黑色
            self.tree.tag_configure('fail', foreground='#FF3333')  # 红色

        # 高亮搜索结果
        search_key = self.search_entry.get().strip()
        if search_key:
            for item in self.tree.get_children():
                values = self.tree.item(item, 'values')
                if search_key.lower() in values[0].lower():
                    self.tree.tag_configure('highlight', background='#FFFACD')
                    self.tree.item(item, tags=('highlight',))

        # 更新统计信息
        if weighted_avg is not None:
            color = '#0066CC' if weighted_avg >= 60 else '#FF3333'
            self.avg_label.config(
                text=f"加权平均分: {weighted_avg:.2f}",
                fg=color
            )

        if total_credit is not None:
            self.credit_label.config(text=f"总学分: {total_credit:.1f}")

    def get_search_keyword(self) -> str:
        # 获取搜索关键词
        return self.search_entry.get().strip()

    def get_all_grades(self) -> Dict[str, Dict[str, float]]:
        # 获取所有成绩数据
        return self.all_grades

    def destroy(self):
        # 销毁界面
        self.frame.destroy()